/*
 * usart_debug.c
 * Project: wifi_module_code
 * Created on: Apr 5, 2013
 * Author: vagabond
 */

/* Includes ------------------------------------------------------------------*/
#include "usart_debug.h"
#include "stm32f4_discovery.h"
#include <stdio.h>
#include "usart_buffer.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/
static usart_buffer dataBuffer = { 0, 0, };/**< received data via USART_DEBUGs*/
/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/
/**
 * @brief Retarget printf to USART_DEBUG
 * @param ch :The int promotion of the character to be written.
 The value is internally converted to an unsigned char when written.
 * @param f :Pointer to a FILE object that identifies an output stream.
 * @return On success, the character written is returned.
 If a writing error occurs, EOF is returned and the error indicator (ferror) is set.
 */
int fputc(int ch, FILE *f) {
	/* Place your implementation of fputc here */
	/* e.g. write a character to the USART */
	USART_SendData(USART_DEBUG, (uint8_t) ch);

	/* Loop until the end of transmission */
	while (USART_GetFlagStatus(USART_DEBUG, USART_FLAG_TXE ) == RESET) {
	}

	return ch;
}

/**
 * @brief Config USART_DEBUG
 * @param None
 * @return None
 */
void usartDebugConfiguration() {
	USART_InitTypeDef USART_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	/* Enable GPIO clock */
	RCC_AHB1PeriphClockCmd(USART_DEBUG_TX_GPIO_CLK | USART_DEBUG_RX_GPIO_CLK,
			ENABLE);

	/* Enable USART clock */
	USART_DEBUG_CLK_INIT(USART_DEBUG_CLK, ENABLE);

	/* Connect USART pins to AF7 */
	GPIO_PinAFConfig(USART_DEBUG_TX_GPIO_PORT, USART_DEBUG_TX_SOURCE,
			USART_DEBUG_TX_AF );
	GPIO_PinAFConfig(USART_DEBUG_RX_GPIO_PORT, USART_DEBUG_RX_SOURCE,
			USART_DEBUG_RX_AF );

	/* Configure USART Tx and Rx as alternate function push-pull */
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Pin = USART_DEBUG_TX_PIN;
	GPIO_Init(USART_DEBUG_TX_GPIO_PORT, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = USART_DEBUG_RX_PIN;
	GPIO_Init(USART_DEBUG_RX_GPIO_PORT, &GPIO_InitStructure);

	/* Enable the USART OverSampling by 8 */
	USART_OverSampling8Cmd(USART_DEBUG, ENABLE);

	/* USART_DEBUG configuration ----------------------------------------------------*/
	/* USART_DEBUG configured as follow:
	 - BaudRate = 5250000 baud
	 - Maximum BaudRate that can be achieved when using the Oversampling by 8
	 is: (USART APB Clock / 8)
	 Example:
	 - (USART3 APB1 Clock / 8) = (42 MHz / 8) = 5250000 baud
	 - (USART1 APB2 Clock / 8) = (84 MHz / 8) = 10500000 baud
	 - Maximum BaudRate that can be achieved when using the Oversampling by 16
	 is: (USART APB Clock / 16)
	 Example: (USART3 APB1 Clock / 16) = (42 MHz / 16) = 2625000 baud
	 Example: (USART1 APB2 Clock / 16) = (84 MHz / 16) = 5250000 baud
	 - Word Length = 8 Bits
	 - one Stop Bit
	 - No parity
	 - Hardware flow control disabled (RTS and CTS signals)
	 - Receive and transmit enabled
	 */
	USART_InitStructure.USART_BaudRate = 57600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl =
			USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART_DEBUG, &USART_InitStructure);

	/* Enable rx interrupt USART WIFI */
	USART_ITConfig(USART_DEBUG, USART_IT_RXNE, ENABLE);

	/* NVIC configuration */
	/* Configure the Priority Group to 2 bits */
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2 );

	/* Enable the USART_DEBUG Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = USART_DEBUG_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	/* Enable USART */
	USART_Cmd(USART_DEBUG, ENABLE);

}


/**
 * @brief  This function handles USRAT interrupt request.
 * @param  None
 * @retval None
 */
void USART_DEBUG_IRQHandler(void) {

	usart_buffer *p;


	if (USART_GetITStatus(USART_DEBUG, USART_IT_RXNE ) == SET) {
		p = &dataBuffer;

		if (((p->in - p->out) & ~(BUFFER_SIZE - 1)) == 0) {
			p->buf[p->in & (BUFFER_SIZE - 1)] = USART_ReceiveData(USART_DEBUG );
			USART_SendData(USART_DEBUG, p->buf[p->in & (BUFFER_SIZE - 1)]); //echo to terminal
			p->in++;

		}

	}
}
